package mhe.mgt;

import java.util.LinkedList;
import java.util.List;

import mhe.mgt.model.MchMachine;
import mhe.mgt.model.MchSystem;

import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

@SuppressWarnings("unchecked")
public class NavigationView extends ViewPart {
	public static final String ID = "MachineManagement.navigationView";
	public TreeViewer treeViewer;
	private static List<Listener> listeners = new LinkedList<Listener>();
	
	private static NavigationView navigationView;
	
	public NavigationView() {
		navigationView = this;
	}
	
	public static NavigationView instance() {
		return navigationView;
	}
	
	class ViewContentProvider implements IStructuredContentProvider, 
										   ITreeContentProvider {

        public void inputChanged(Viewer v, Object oldInput, Object newInput) {
		}
        
		public void dispose() {
		}
        
		public Object[] getElements(Object parent) {
			return getChildren(parent);
		}
        
		public Object getParent(Object child) {
			if (child instanceof MchMachine) {
				return Application.systemService.find(((MchMachine)child).getSystemId());
			}
			return null;
		}
        
		public Object[] getChildren(Object parent) {
			if (parent instanceof List) {
				return ((List)parent).toArray(new MchSystem[((List)parent).size()]);
			}
			if (parent instanceof MchSystem) {
				return Application.machineService.listBySystemId(((MchSystem)parent).getId());
			}
			return new Object[0];
		}

		public boolean hasChildren(Object parent) {
        	if (parent instanceof List) {
				return !((List)parent).isEmpty();
			}
			if (parent instanceof MchSystem)
				return Application.machineService.listBySystemId(((MchSystem)parent).getId()).length > 0;
			return false;
		}
	}
	
	class ViewLabelProvider extends LabelProvider {

		public String getText(Object obj) {
			if (obj instanceof MchMachine) {
				return ((MchMachine)obj).getName();
			}
			if (obj instanceof MchSystem) {
				return ((MchSystem)obj).getName();
			}
			return obj.toString();
		}
		
		public Image getImage(Object obj) {
			String imageKey = ISharedImages.IMG_ETOOL_PRINT_EDIT;
			if (obj instanceof MchSystem)
			   imageKey = ISharedImages.IMG_ETOOL_HOME_NAV;
			return PlatformUI.getWorkbench().getSharedImages().getImage(imageKey);
		}
	}

	/**
     * This is a callback that will allow us to create the viewer and initialize
     * it.
     */
	public void createPartControl(Composite parent) {
		treeViewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION);
		treeViewer.setContentProvider(new ViewContentProvider());
		treeViewer.setLabelProvider(new ViewLabelProvider());
		treeViewer.setInput(Application.systemService.list());
		
		treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			   public void selectionChanged(SelectionChangedEvent event) {
			       // if the selection is empty clear the label
			       if(event.getSelection().isEmpty()) {
			           return;
			       }
			       if(event.getSelection() instanceof IStructuredSelection) {
			           IStructuredSelection selection = (IStructuredSelection)event.getSelection();
			           if (!selection.isEmpty()) {
			        	   notifySelectionListener(selection.getFirstElement());
			           }
			       }
			   }
			});
	}
	
	public void notifySelectionListener(Object obj) {
		for (Listener l : listeners) {
			Event event = new Event();
			event.data = obj;
			l.handleEvent(event);
		}
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		treeViewer.getControl().setFocus();
	}

	public void refresh() {
		treeViewer.setInput(Application.systemService.list());
		treeViewer.refresh();
	}

	public static void addSelectionListener(Listener listener) {
		listeners.add(listener);
	}
	
	public void removeSelectionListener(Listener listener) {
		listeners.remove(listener);
	}
}